home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: mload.cpp
- //
- // Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
-
- #include <windows.h>
- #include <mmsystem.h>
- #include <objbase.h>
- #include <malloc.h> // _alloca
- #include <stdio.h>
- #include <d3d8.h>
- #include <d3dx8.h>
- #include "resource.h"
- #include "D3DApp.h"
- #include "D3DFont.h"
- #include "D3DUtil.h"
- #include "DXUtil.h"
- #include "D3DRes.h"
- #include "rmxfguid.h"
- #include "rmxftmpl.h"
- #include "dxutil.h"
- #include "SkinnedMesh.h"
-
-
- HRESULT CalculateSum(SFrame *pframe, D3DXMATRIX *pmatCur, D3DXVECTOR3 *pvCenter,
- UINT *pcVertices)
- {
- HRESULT hr = S_OK;
- PBYTE pbPoints = NULL;
- UINT cVerticesLocal = 0;
- PBYTE pbCur;
- D3DXVECTOR3 *pvCur;
- D3DXVECTOR3 vTransformedCur;
- UINT iPoint;
- SMeshContainer *pmcCur;
- SFrame *pframeCur;
- UINT cVertices;
- D3DXMATRIX matLocal;
-
- D3DXMatrixMultiply(&matLocal, &pframe->matRot, pmatCur);
-
- pmcCur = pframe->pmcMesh;
- while (pmcCur != NULL)
- {
- DWORD fvfsize = D3DXGetFVFVertexSize(pmcCur->pMesh->GetFVF());
-
- cVertices = pmcCur->pMesh->GetNumVertices();
-
- hr = pmcCur->pMesh->LockVertexBuffer(0, &pbPoints);
- if (FAILED(hr))
- goto e_Exit;
-
- for( iPoint=0, pbCur = pbPoints; iPoint < cVertices; iPoint++, pbCur += fvfsize)
- {
- pvCur = (D3DXVECTOR3*)pbCur;
-
- if ((pvCur->x != 0.0) || (pvCur->y != 0.0) || (pvCur->z != 0.0))
- {
- cVerticesLocal++;
-
- D3DXVec3TransformCoord(&vTransformedCur, pvCur, &matLocal);
-
- pvCenter->x += vTransformedCur.x;
- pvCenter->y += vTransformedCur.y;
- pvCenter->z += vTransformedCur.z;
- }
- }
-
-
- pmcCur->pMesh->UnlockVertexBuffer();
- pbPoints = NULL;
-
- pmcCur = pmcCur->pmcNext;
- }
-
- *pcVertices += cVerticesLocal;
-
- pframeCur = pframe->pframeFirstChild;
- while (pframeCur != NULL)
- {
- hr = CalculateSum(pframeCur, &matLocal, pvCenter, pcVertices);
- if (FAILED(hr))
- goto e_Exit;
-
- pframeCur = pframeCur->pframeSibling;
- }
-
- e_Exit:
- if (pbPoints != NULL)
- {
- pmcCur->pMesh->UnlockVertexBuffer();
- }
-
- return hr;
- }
-
-
-
-
- HRESULT CalculateRadius(SFrame *pframe, D3DXMATRIX *pmatCur, D3DXVECTOR3 *pvCenter,
- float *pfRadiusSq)
- {
- HRESULT hr = S_OK;
- PBYTE pbPoints = NULL;
- PBYTE pbCur;
- D3DXVECTOR3 *pvCur;
- D3DXVECTOR3 vDist;;
- UINT iPoint;
- UINT cVertices;
- SMeshContainer *pmcCur;
- SFrame *pframeCur;
- float fRadiusLocalSq;
- float fDistSq;
- D3DXMATRIX matLocal;
-
- D3DXMatrixMultiply(&matLocal, &pframe->matRot, pmatCur);
-
- pmcCur = pframe->pmcMesh;
- fRadiusLocalSq = *pfRadiusSq;
- while (pmcCur != NULL)
- {
- DWORD fvfsize = D3DXGetFVFVertexSize(pmcCur->pMesh->GetFVF());
-
- cVertices = pmcCur->pMesh->GetNumVertices();
-
- hr = pmcCur->pMesh->LockVertexBuffer(0, &pbPoints);
- if (FAILED(hr))
- goto e_Exit;
-
- for( iPoint=0, pbCur = pbPoints; iPoint < cVertices; iPoint++, pbCur += fvfsize )
- {
- pvCur = (D3DXVECTOR3*)pbCur;
-
- if ((pvCur->x == 0.0) && (pvCur->y == 0.0) && (pvCur->z == 0.0))
- continue;
-
- D3DXVec3TransformCoord(&vDist, pvCur, &matLocal);
-
- vDist -= *pvCenter;
-
- fDistSq = D3DXVec3LengthSq(&vDist);
-
- if( fDistSq > fRadiusLocalSq )
- fRadiusLocalSq = fDistSq;
- }
-
-
- pmcCur->pMesh->UnlockVertexBuffer();
- pbPoints = NULL;
-
- pmcCur = pmcCur->pmcNext;
- }
-
- *pfRadiusSq = fRadiusLocalSq;
-
- pframeCur = pframe->pframeFirstChild;
- while (pframeCur != NULL)
- {
- hr = CalculateRadius(pframeCur, &matLocal, pvCenter, pfRadiusSq);
- if (FAILED(hr))
- goto e_Exit;
-
- pframeCur = pframeCur->pframeSibling;
- }
-
- e_Exit:
- if (pbPoints != NULL)
- {
- pmcCur->pMesh->UnlockVertexBuffer();
- }
-
- return hr;
- }
-
-
-
-
- HRESULT CalculateBoundingSphere(SDrawElement *pdeCur)
- {
- HRESULT hr = S_OK;
- D3DXVECTOR3 vCenter(0,0,0);
- UINT cVertices = 0;
- float fRadiusSq = 0;
- D3DXMATRIX matCur;
-
- D3DXMatrixIdentity(&matCur);
- hr = CalculateSum(pdeCur->pframeRoot, &matCur, &vCenter, &cVertices);
- if (FAILED(hr))
- goto e_Exit;
-
- if (cVertices > 0)
- {
- vCenter /= (float)cVertices;
-
- D3DXMatrixIdentity(&matCur);
- hr = CalculateRadius(pdeCur->pframeRoot, &matCur, &vCenter, &fRadiusSq);
- if (FAILED(hr))
- goto e_Exit;
- }
-
- pdeCur->fRadius = (float)sqrt((double)fRadiusSq);;
- pdeCur->vCenter = vCenter;
- e_Exit:
- return hr;
- }
-
-
-
-
- HRESULT CMyD3DApplication::FindBones(SFrame *pframeCur, SDrawElement *pde)
- {
- HRESULT hr = S_OK;
- SMeshContainer *pmcMesh;
- SFrame *pframeChild;
-
- pmcMesh = pframeCur->pmcMesh;
- while (pmcMesh != NULL)
- {
- if (pmcMesh->m_pSkinMesh)
- {
- char** pBoneName = static_cast<char**>(pmcMesh->m_pBoneNamesBuf->GetBufferPointer());
- for (DWORD i = 0; i < pmcMesh->m_pSkinMesh->GetNumBones(); ++i)
- {
- SFrame* pFrame = pde->FindFrame(pBoneName[i]);
- pmcMesh->m_pBoneMatrix[i] = &(pFrame->matCombined);
- }
- }
- pmcMesh = pmcMesh->pmcNext;
- }
-
- pframeChild = pframeCur->pframeFirstChild;
- while (pframeChild != NULL)
- {
- hr = FindBones(pframeChild, pde);
- if (FAILED(hr))
- return hr;
-
- pframeChild = pframeChild->pframeSibling;
- }
-
- return S_OK;
- }
-
-
-
-
- HRESULT CMyD3DApplication::LoadMeshHierarchy()
- {
- TCHAR* pszFile = m_szPath;
- SDrawElement *pdeMesh = NULL;
- HRESULT hr = S_OK;
- LPDIRECTXFILE pxofapi = NULL;
- LPDIRECTXFILEENUMOBJECT pxofenum = NULL;
- LPDIRECTXFILEDATA pxofobjCur = NULL;
- DWORD dwOptions;
- int cchFileName;
-
- if (pszFile == NULL)
- return E_INVALIDARG;
-
- pdeMesh = new SDrawElement();
-
- delete pdeMesh->pframeRoot;
- pdeMesh->pframeAnimHead = NULL;
-
- pdeMesh->pframeRoot = new SFrame();
- if (pdeMesh->pframeRoot == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
-
- dwOptions = 0;
-
- cchFileName = strlen(pszFile);
- if (cchFileName < 2)
- {
- hr = E_FAIL;
- goto e_Exit;
- }
-
- hr = DirectXFileCreate(&pxofapi);
- if (FAILED(hr))
- goto e_Exit;
-
- // Register templates for d3drm.
- hr = pxofapi->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES,
- D3DRM_XTEMPLATE_BYTES);
- if (FAILED(hr))
- goto e_Exit;
-
- // Create enum object.
- hr = pxofapi->CreateEnumObject((LPVOID)pszFile,
- DXFILELOAD_FROMFILE,
- &pxofenum);
- if (FAILED(hr))
- goto e_Exit;
-
-
- // Enumerate top level objects.
- // Top level objects are always data object.
- while (SUCCEEDED(pxofenum->GetNextDataObject(&pxofobjCur)))
- {
- hr = LoadFrames(pxofobjCur, pdeMesh, dwOptions, m_dwFVF,
- m_pd3dDevice,
- pdeMesh->pframeRoot);
- GXRELEASE(pxofobjCur);
-
- if (FAILED(hr))
- goto e_Exit;
- }
-
- hr = FindBones(pdeMesh->pframeRoot, pdeMesh);
- if (FAILED(hr))
- goto e_Exit;
-
-
- delete []pdeMesh->szName;
- pdeMesh->szName = new char[cchFileName+1];
- if (pdeMesh->szName == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
- memcpy(pdeMesh->szName, pszFile, cchFileName+1);
-
- // delete the current mesh, now that the load has succeeded
- DeleteSelectedMesh();
-
- // link into the draw list
- pdeMesh->pdeNext = m_pdeHead;
- m_pdeHead = pdeMesh;
-
- m_pdeSelected = pdeMesh;
- m_pmcSelectedMesh = pdeMesh->pframeRoot->pmcMesh;
-
-
- m_pframeSelected = pdeMesh->pframeRoot;
-
- hr = CalculateBoundingSphere(pdeMesh);
- if (FAILED(hr))
- goto e_Exit;
-
- SetProjectionMatrix();
-
- m_pdeSelected->fCurTime = 0.0f;
- m_pdeSelected->fMaxTime = 200.0f;
-
- D3DXMatrixTranslation(&m_pdeSelected->pframeRoot->matRot,
- -pdeMesh->vCenter.x, -pdeMesh->vCenter.y, -pdeMesh->vCenter.z);
- m_pdeSelected->pframeRoot->matRotOrig = m_pdeSelected->pframeRoot->matRot;
-
- e_Exit:
- GXRELEASE(pxofobjCur);
- GXRELEASE(pxofenum);
- GXRELEASE(pxofapi);
-
- if (FAILED(hr))
- {
- delete pdeMesh;
- }
-
- return hr;
- }
-
-
-
-
- HRESULT CMyD3DApplication::LoadAnimation(LPDIRECTXFILEDATA pxofobjCur, SDrawElement *pde,
- DWORD options, DWORD fvf, LPDIRECT3DDEVICE8 pD3DDevice,
- SFrame *pframeParent)
- {
- HRESULT hr = S_OK;
- SRotateKeyXFile *pFileRotateKey;
- SScaleKeyXFile *pFileScaleKey;
- SPositionKeyXFile *pFilePosKey;
- SMatrixKeyXFile *pFileMatrixKey;
- SFrame *pframeCur;
- LPDIRECTXFILEDATA pxofobjChild = NULL;
- LPDIRECTXFILEOBJECT pxofChild = NULL;
- LPDIRECTXFILEDATAREFERENCE pxofobjChildRef = NULL;
- const GUID *type;
- DWORD dwSize;
- PBYTE pData;
- DWORD dwKeyType;
- DWORD cKeys;
- DWORD iKey;
- DWORD cchName;
- char *szFrameName;
-
- pframeCur = new SFrame();
- if (pframeCur == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
- pframeCur->bAnimationFrame = true;
-
- pframeParent->AddFrame(pframeCur);
- pde->AddAnimationFrame(pframeCur);
-
- // Enumerate child objects.
- // Child object can be data, data reference or binary.
- // Use QueryInterface() to find what type of object a child is.
- while (SUCCEEDED(pxofobjCur->GetNextObject(&pxofChild)))
- {
- // Query the child for it's FileDataReference
- hr = pxofChild->QueryInterface(IID_IDirectXFileDataReference,
- (LPVOID *)&pxofobjChildRef);
- if (SUCCEEDED(hr))
- {
- hr = pxofobjChildRef->Resolve(&pxofobjChild);
- if (SUCCEEDED(hr))
- {
- hr = pxofobjChild->GetType(&type);
- if (FAILED(hr))
- goto e_Exit;
-
- if( TID_D3DRMFrame == *type )
- {
- if (pframeCur->pframeToAnimate != NULL)
- {
- hr = E_INVALIDARG;
- goto e_Exit;
- }
-
- hr = pxofobjChild->GetName(NULL, &cchName);
- if (FAILED(hr))
- goto e_Exit;
-
- if (cchName == 0)
- {
- hr = E_INVALIDARG;
- goto e_Exit;
-
- }
-
- szFrameName = (char*)_alloca(cchName);
- if (szFrameName == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- hr = pxofobjChild->GetName(szFrameName, &cchName);
- if (FAILED(hr))
- goto e_Exit;
-
- pframeCur->pframeToAnimate = pde->FindFrame(szFrameName);
- if (pframeCur->pframeToAnimate == NULL)
- {
- hr = E_INVALIDARG;
- goto e_Exit;
- }
- }
-
- GXRELEASE(pxofobjChild);
- }
-
- GXRELEASE(pxofobjChildRef);
- }
- else
- {
-
- // Query the child for it's FileData
- hr = pxofChild->QueryInterface(IID_IDirectXFileData,
- (LPVOID *)&pxofobjChild);
- if (SUCCEEDED(hr))
- {
- hr = pxofobjChild->GetType(&type);
- if (FAILED(hr))
- goto e_Exit;
-
- if ( TID_D3DRMFrame == *type )
- {
- hr = LoadFrames(pxofobjChild, pde, options, fvf, pD3DDevice, pframeCur);
- if (FAILED(hr))
- goto e_Exit;
- }
- else if ( TID_D3DRMAnimationOptions == *type )
- {
- //ParseAnimOptions(pChildData,pParentFrame);
- //i=2;
- }
- else if ( TID_D3DRMAnimationKey == *type )
- {
- hr = pxofobjChild->GetData( NULL, &dwSize, (PVOID*)&pData );
- if (FAILED(hr))
- goto e_Exit;
-
- dwKeyType = ((DWORD*)pData)[0];
- cKeys = ((DWORD*)pData)[1];
-
- if (dwKeyType == 0)
- {
- if (pframeCur->m_pRotateKeys != NULL)
- {
- hr = E_INVALIDARG;
- goto e_Exit;
- }
-
- pframeCur->m_pRotateKeys = new SRotateKey[cKeys];
- if (pframeCur->m_pRotateKeys == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- pframeCur->m_cRotateKeys = cKeys;
- //NOTE x files are w x y z and QUATERNIONS are x y z w
-
- pFileRotateKey = (SRotateKeyXFile*)(pData + (sizeof(DWORD) * 2));
- for (iKey = 0;iKey < cKeys; iKey++)
- {
- pframeCur->m_pRotateKeys[iKey].dwTime = pFileRotateKey->dwTime;
- pframeCur->m_pRotateKeys[iKey].quatRotate.x = pFileRotateKey->x;
- pframeCur->m_pRotateKeys[iKey].quatRotate.y = pFileRotateKey->y;
- pframeCur->m_pRotateKeys[iKey].quatRotate.z = pFileRotateKey->z;
- pframeCur->m_pRotateKeys[iKey].quatRotate.w = pFileRotateKey->w;
-
- pFileRotateKey += 1;
- }
- }
- else if (dwKeyType == 1)
- {
- if (pframeCur->m_pScaleKeys != NULL)
- {
- hr = E_INVALIDARG;
- goto e_Exit;
- }
-
- pframeCur->m_pScaleKeys = new SScaleKey[cKeys];
- if (pframeCur->m_pScaleKeys == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- pframeCur->m_cScaleKeys = cKeys;
-
- pFileScaleKey = (SScaleKeyXFile*)(pData + (sizeof(DWORD) * 2));
- for (iKey = 0;iKey < cKeys; iKey++)
- {
- pframeCur->m_pScaleKeys[iKey].dwTime = pFileScaleKey->dwTime;
- pframeCur->m_pScaleKeys[iKey].vScale = pFileScaleKey->vScale;
-
- pFileScaleKey += 1;
- }
- }
- else if (dwKeyType == 2)
- {
- if (pframeCur->m_pPositionKeys != NULL)
- {
- hr = E_INVALIDARG;
- goto e_Exit;
- }
-
- pframeCur->m_pPositionKeys = new SPositionKey[cKeys];
- if (pframeCur->m_pPositionKeys == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- pframeCur->m_cPositionKeys = cKeys;
-
- pFilePosKey = (SPositionKeyXFile*)(pData + (sizeof(DWORD) * 2));
- for (iKey = 0;iKey < cKeys; iKey++)
- {
- pframeCur->m_pPositionKeys[iKey].dwTime = pFilePosKey->dwTime;
- pframeCur->m_pPositionKeys[iKey].vPos = pFilePosKey->vPos;
-
- pFilePosKey += 1;
- }
- }
- else if (dwKeyType == 4)
- {
- if (pframeCur->m_pMatrixKeys != NULL)
- {
- hr = E_INVALIDARG;
- goto e_Exit;
- }
-
- pframeCur->m_pMatrixKeys = new SMatrixKey[cKeys];
- if (pframeCur->m_pMatrixKeys == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- pframeCur->m_cMatrixKeys = cKeys;
-
- pFileMatrixKey = (SMatrixKeyXFile*)(pData + (sizeof(DWORD) * 2));
- for (iKey = 0;iKey < cKeys; iKey++)
- {
- pframeCur->m_pMatrixKeys[iKey].dwTime = pFileMatrixKey->dwTime;
- pframeCur->m_pMatrixKeys[iKey].mat = pFileMatrixKey->mat;
-
- pFileMatrixKey += 1;
- }
- }
- else
- {
- hr = E_INVALIDARG;
- goto e_Exit;
- }
- }
-
- GXRELEASE(pxofobjChild);
- }
- }
-
- GXRELEASE(pxofChild);
- }
-
- e_Exit:
- GXRELEASE(pxofobjChild);
- GXRELEASE(pxofChild);
- GXRELEASE(pxofobjChildRef);
- return hr;
- }
-
-
-
-
- HRESULT CMyD3DApplication::LoadAnimationSet(LPDIRECTXFILEDATA pxofobjCur, SDrawElement *pde,
- DWORD options, DWORD fvf, LPDIRECT3DDEVICE8 pD3DDevice,
- SFrame *pframeParent)
- {
- SFrame *pframeCur;
- const GUID *type;
- HRESULT hr = S_OK;
- LPDIRECTXFILEDATA pxofobjChild = NULL;
- LPDIRECTXFILEOBJECT pxofChild = NULL;
- DWORD cchName;
-
- pframeCur = new SFrame();
- if (pframeCur == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
- pframeCur->bAnimationFrame = true;
-
- pframeParent->AddFrame(pframeCur);
-
- hr = pxofobjCur->GetName(NULL, &cchName);
- if (FAILED(hr))
- goto e_Exit;
-
- if (cchName > 0)
- {
- pframeCur->szName = new char[cchName];
- if (pframeCur->szName == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- hr = pxofobjCur->GetName(pframeCur->szName, &cchName);
- if (FAILED(hr))
- goto e_Exit;
- }
-
-
- // Enumerate child objects.
- // Child object can be data, data reference or binary.
- // Use QueryInterface() to find what type of object a child is.
- while (SUCCEEDED(pxofobjCur->GetNextObject(&pxofChild)))
- {
- // Query the child for it's FileData
- hr = pxofChild->QueryInterface(IID_IDirectXFileData,
- (LPVOID *)&pxofobjChild);
- if (SUCCEEDED(hr))
- {
- hr = pxofobjChild->GetType(&type);
- if (FAILED(hr))
- goto e_Exit;
-
- if( TID_D3DRMAnimation == *type )
- {
- hr = LoadAnimation(pxofobjChild, pde, options, fvf, pD3DDevice, pframeCur);
- if (FAILED(hr))
- goto e_Exit;
- }
-
- GXRELEASE(pxofobjChild);
- }
-
- GXRELEASE(pxofChild);
- }
-
- e_Exit:
- GXRELEASE(pxofobjChild);
- GXRELEASE(pxofChild);
- return hr;
- }
-
-
-
-
- HRESULT SplitMesh
- (
- LPD3DXMESH pMesh, // ASSUMPTION: *pMesh is attribute sorted & has a valid attribute table
- DWORD iAttrSplit, // **ppMeshB gets the mesh comprising of this attribute range onward
- DWORD* rgiAdjacency,
- DWORD optionsA,
- DWORD optionsB,
- LPD3DXMESH* ppMeshA,
- LPD3DXMESH* ppMeshB
- )
- {
- *ppMeshA = NULL;
-
- *ppMeshB = NULL;
-
-
- HRESULT hr = S_OK;
-
- PBYTE pbVerticesIn = NULL;
- PBYTE pbIndicesIn = NULL;
- DWORD* piAttribsIn = NULL;
-
- LPD3DXMESH pMeshA = NULL;
- LPD3DXMESH pMeshB = NULL;
-
- LPD3DXBUFFER pVertexRemapA = NULL;
- LPD3DXBUFFER pVertexRemapB = NULL;
-
- DWORD* rgiAdjacencyA = NULL;
- DWORD* rgiAdjacencyB = NULL;
-
-
-
-
- LPDIRECT3DDEVICE8 pDevice = NULL;
-
-
- D3DXATTRIBUTERANGE* rgAttrTable = NULL;
-
- DWORD cAttrTable = 0;
-
-
-
- DWORD cVerticesA;
- DWORD cVerticesB;
-
- DWORD cFacesA;
- DWORD cFacesB;
-
- DWORD cbVertexSize;
-
- DWORD dw32bit;
-
-
- dw32bit = pMesh->GetOptions() & D3DXMESH_32BIT;
-
- cbVertexSize = D3DXGetFVFVertexSize(pMesh->GetFVF());
-
- hr = pMesh->GetDevice(&pDevice);
-
- if (FAILED(hr))
- goto e_Exit;
-
-
- hr = pMesh->GetAttributeTable(NULL, &cAttrTable);
-
- if (FAILED(hr))
- goto e_Exit;
-
-
- rgAttrTable = new D3DXATTRIBUTERANGE[cAttrTable];
-
- if (rgAttrTable == NULL)
- {
- hr = E_OUTOFMEMORY;
-
- goto e_Exit;
- }
-
-
- hr = pMesh->GetAttributeTable(rgAttrTable, NULL);
-
- if (FAILED(hr))
- goto e_Exit;
-
- if (iAttrSplit == 0)
- {
- cVerticesA = 0;
-
- cFacesA = 0;
- }
- else if (iAttrSplit >= cAttrTable)
- {
- cVerticesA = pMesh->GetNumVertices();
-
- cFacesA = pMesh->GetNumFaces();
- }
- else
- {
- cVerticesA = rgAttrTable[iAttrSplit].VertexStart;
-
- cFacesA = rgAttrTable[iAttrSplit].FaceStart;
- }
-
- cVerticesB = pMesh->GetNumVertices() - cVerticesA;
-
- cFacesB = pMesh->GetNumFaces() - cFacesA;
-
-
- hr = pMesh->LockVertexBuffer(D3DLOCK_READONLY, &pbVerticesIn);
-
- if (FAILED(hr))
- goto e_Exit;
-
-
- hr = pMesh->LockIndexBuffer(D3DLOCK_READONLY, &pbIndicesIn);
-
- if (FAILED(hr))
- goto e_Exit;
-
-
- hr = pMesh->LockAttributeBuffer(D3DLOCK_READONLY, &piAttribsIn);
-
- if (FAILED(hr))
- goto e_Exit;
-
-
- if (cFacesA && cVerticesA)
- {
- PBYTE pbVerticesOut = NULL;
- PBYTE pbIndicesOut = NULL;
- DWORD* piAttribsOut = NULL;
- DWORD i;
-
- hr = D3DXCreateMeshFVF(cFacesA, cVerticesA, optionsA | dw32bit, pMesh->GetFVF(), pDevice, &pMeshA);
-
- if (FAILED(hr))
- goto e_ExitA;
-
-
- hr = pMeshA->LockVertexBuffer(0, &pbVerticesOut);
-
- if (FAILED(hr))
- goto e_ExitA;
-
-
- hr = pMeshA->LockIndexBuffer(0, (LPBYTE*)&pbIndicesOut);
-
- if (FAILED(hr))
- goto e_ExitA;
-
-
- hr = pMeshA->LockAttributeBuffer(0, &piAttribsOut);
-
- if (FAILED(hr))
- goto e_ExitA;
-
-
- memcpy(pbVerticesOut, pbVerticesIn, cVerticesA * cbVertexSize * sizeof(BYTE));
-
- if (dw32bit)
- {
- memcpy(pbIndicesOut, pbIndicesIn, cFacesA * 3 * sizeof(DWORD));
- }
- else
- {
- memcpy(pbIndicesOut, pbIndicesIn, cFacesA * 3 * sizeof(WORD));
- }
-
-
- memcpy(piAttribsOut, piAttribsIn, cFacesA * sizeof(DWORD));
-
-
- rgiAdjacencyA = new DWORD[cFacesA * 3];
-
- if (rgiAdjacencyA == NULL)
- {
- hr = E_OUTOFMEMORY;
-
- goto e_ExitA;
- }
-
-
- for (i = 0; i < cFacesA * 3; i++)
- {
- rgiAdjacencyA[i] = (rgiAdjacency[i] < cFacesA) ? rgiAdjacency[i] : 0xFFFFFFFF;
- }
-
-
- e_ExitA:
-
- if (pbVerticesOut != NULL)
- {
- pMeshA->UnlockVertexBuffer();
- }
-
-
- if (pbIndicesOut != NULL)
- {
- pMeshA->UnlockIndexBuffer();
- }
-
-
- if (piAttribsOut != NULL)
- {
- pMeshA->UnlockAttributeBuffer();
- }
-
-
- if (FAILED(hr))
- goto e_Exit;
- }
-
-
- // calculate Mesh A's attribute table
-
- if (pMeshA != NULL)
- {
- hr = pMeshA->OptimizeInplace
- (
- D3DXMESHOPT_VERTEXCACHE,
- rgiAdjacencyA,
- NULL,
- NULL,
- &pVertexRemapA
- );
-
- if (FAILED(hr))
- goto e_Exit;
- }
-
-
- if (cFacesB && cVerticesB)
- {
- PBYTE pbVerticesOut = NULL;
- PBYTE pbIndicesOut = NULL;
- DWORD* piAttribsOut = NULL;
- DWORD i;
-
- hr = D3DXCreateMeshFVF(cFacesB, cVerticesB, optionsB | dw32bit, pMesh->GetFVF(), pDevice, &pMeshB);
-
- if (FAILED(hr))
- goto e_ExitB;
-
-
- hr = pMeshB->LockVertexBuffer(0, &pbVerticesOut);
-
- if (FAILED(hr))
- goto e_ExitB;
-
-
- hr = pMeshB->LockIndexBuffer(0, &pbIndicesOut);
-
- if (FAILED(hr))
- goto e_ExitB;
-
-
- hr = pMeshB->LockAttributeBuffer(0, &piAttribsOut);
-
- if (FAILED(hr))
- goto e_ExitB;
-
-
- memcpy(pbVerticesOut, pbVerticesIn + (cVerticesA * cbVertexSize), cVerticesB * cbVertexSize * sizeof(BYTE));
-
-
- // copy & renumber indices
-
- if (dw32bit)
- {
- for (DWORD i = 0; i < cFacesB * 3; i++)
- {
- ((DWORD*)pbIndicesOut)[i] = ((DWORD*)pbIndicesIn)[(cFacesA * 3) + i] - (DWORD)cVerticesA;
- }
- }
- else
- {
- for (DWORD i = 0; i < cFacesB * 3; i++)
- {
- ((WORD*)pbIndicesOut)[i] = ((WORD*)pbIndicesIn)[(cFacesA * 3) + i] - (WORD)cVerticesA;
- }
- }
-
- memcpy(piAttribsOut, piAttribsIn + cFacesA, cFacesB * sizeof(DWORD));
-
-
- rgiAdjacencyB = new DWORD[cFacesB * 3];
-
- if (rgiAdjacencyB == NULL)
- {
- hr = E_OUTOFMEMORY;
-
- goto e_ExitB;
- }
-
-
- // copy & renumber adjacency
-
- for (i = 0; i < cFacesB * 3; i++)
- {
- rgiAdjacencyB[i] = (rgiAdjacency[(cFacesA * 3) + i] >= cFacesA && rgiAdjacency[(cFacesA * 3) + i] != 0xFFFFFFFF) ? rgiAdjacency[(cFacesA * 3) + i] - cFacesA : 0xFFFFFFFF;
- }
-
-
- e_ExitB:
-
- if (pbVerticesOut != NULL)
- {
- pMeshB->UnlockVertexBuffer();
- }
-
-
- if (pbIndicesOut != NULL)
- {
- pMeshB->UnlockIndexBuffer();
- }
-
-
- if (piAttribsOut != NULL)
- {
- pMeshB->UnlockAttributeBuffer();
- }
-
-
- if (FAILED(hr))
- goto e_Exit;
- }
-
-
- // calculate Mesh B's attribute table
-
- if (pMeshB != NULL)
- {
- hr = pMeshB->OptimizeInplace
- (
- D3DXMESHOPT_ATTRSORT,
- rgiAdjacencyB,
- NULL,
- NULL,
- &pVertexRemapB
- );
-
- if (FAILED(hr))
- goto e_Exit;
- }
-
-
- e_Exit:
-
- if (rgAttrTable != NULL)
- {
- delete[] rgAttrTable;
- }
-
- if (pbVerticesIn != NULL)
- {
- pMesh->UnlockVertexBuffer();
- }
-
- if (pbIndicesIn != NULL)
- {
- pMesh->UnlockIndexBuffer();
- }
-
- if (piAttribsIn != NULL)
- {
- pMesh->UnlockAttributeBuffer();
- }
-
- if (rgiAdjacencyA != NULL)
- {
- delete[] rgiAdjacencyA;
- }
-
- if (rgiAdjacencyB != NULL)
- {
- delete[] rgiAdjacencyB;
- }
-
- GXRELEASE(pDevice);
-
- GXRELEASE(pVertexRemapA);
-
- GXRELEASE(pVertexRemapB);
-
- if (FAILED(hr))
- {
- GXRELEASE(pMeshA);
-
- GXRELEASE(pMeshB);
-
- pMeshA = NULL;
-
- pMeshB = NULL;
- }
-
- *ppMeshA = pMeshA;
-
- *ppMeshB = pMeshB;
-
- return hr;
- }
-
-
-
-
- HRESULT CMyD3DApplication::GenerateMesh(SMeshContainer *pmcMesh)
- {
- // ASSUMPTION: pmcMesh->m_rgiAdjacency contains the current adjacency
-
- HRESULT hr = S_OK;
-
- DWORD* pAdjacencyIn = NULL;
-
- DWORD cFaces = pmcMesh->m_pSkinMesh->GetNumFaces();
-
- pAdjacencyIn = new DWORD[pmcMesh->m_pSkinMesh->GetNumFaces() * 3];
-
- if (pAdjacencyIn == NULL)
- {
- hr = E_OUTOFMEMORY;
-
- goto e_Exit;
- }
-
- memcpy(pAdjacencyIn, pmcMesh->m_rgiAdjacency, cFaces * 3 * sizeof(DWORD));
-
-
- GXRELEASE(pmcMesh->pMesh);
- GXRELEASE(pmcMesh->pMeshHW);
- GXRELEASE(pmcMesh->pMeshSW);
-
- pmcMesh->pMesh = NULL;
- pmcMesh->pMeshHW = NULL;
- pmcMesh->pMeshSW = NULL;
-
- if (m_method == D3DNONINDEXED)
- {
- DWORD* rgiAdjacency = NULL;
-
- LPDIRECT3DDEVICE8 pDevice = NULL;
-
-
- LPD3DXBONECOMBINATION rgBoneCombinations;
-
- D3DCAPS8 caps;
-
-
- rgiAdjacency = new DWORD[cFaces * 3];
-
- if (rgiAdjacency == NULL)
- {
- hr = E_OUTOFMEMORY;
-
- goto e_ExitNONINDEXED;
- }
-
-
- hr = pmcMesh->m_pSkinMesh->ConvertToBlendedMesh
- (
- 0,
- pAdjacencyIn,
- rgiAdjacency,
- &pmcMesh->cpattr,
- &pmcMesh->m_pBoneCombinationBuf,
- &pmcMesh->pMesh
- );
- if (FAILED(hr))
- goto e_ExitNONINDEXED;
-
-
-
- // calculate the max face influence count
-
- if ((pmcMesh->pMesh->GetFVF() & D3DFVF_POSITION_MASK) != D3DFVF_XYZ)
- {
- pmcMesh->m_maxFaceInfl = 1 + ((pmcMesh->pMesh->GetFVF() & D3DFVF_POSITION_MASK) - D3DFVF_XYZRHW) / 2;
- }
- else
- {
- pmcMesh->m_maxFaceInfl = 1;
- }
-
-
-
- hr = pmcMesh->pMesh->GetDevice(&pDevice);
-
- if (FAILED(hr))
- goto e_ExitNONINDEXED;
-
-
- hr = pDevice->GetDeviceCaps(&caps);
-
- if (FAILED(hr))
- goto e_ExitNONINDEXED;
-
- /* If the device can only do 2 matrix blends, ConvertToBlendedMesh cannot approximate all meshes to it
- Thus we split the mesh in two parts: The part that uses at most 2 matrices and the rest. The first is
- drawn using the device's HW vertex processing and the rest is drawn using SW vertex processing. */
- if (caps.MaxVertexBlendMatrices == 2)
- {
-
- // calculate the index of the attribute table to split on
-
- rgBoneCombinations = reinterpret_cast<LPD3DXBONECOMBINATION>(pmcMesh->m_pBoneCombinationBuf->GetBufferPointer());
-
- for (pmcMesh->iAttrSplit = 0; pmcMesh->iAttrSplit < pmcMesh->cpattr; pmcMesh->iAttrSplit++)
- {
- DWORD cInfl = 0;
-
- for (DWORD iInfl = 0; iInfl < pmcMesh->m_maxFaceInfl; iInfl++)
- {
- if (rgBoneCombinations[pmcMesh->iAttrSplit].BoneId[iInfl] != UINT_MAX)
- {
- ++cInfl;
- }
- }
-
- if (cInfl > 2)
- {
- break;
- }
- }
-
- // split the mesh
-
- hr = SplitMesh(pmcMesh->pMesh, pmcMesh->iAttrSplit, rgiAdjacency, D3DXMESH_WRITEONLY, pmcMesh->pMesh->GetOptions() | D3DXMESH_SYSTEMMEM, &pmcMesh->pMeshHW, &pmcMesh->pMeshSW);
-
- if (FAILED(hr))
- goto e_ExitNONINDEXED;
- }
- else
- {
- // Vertex cache optimize the mesh
- LPD3DXMESH pMeshOpt;
- hr = pmcMesh->pMesh->Optimize(D3DXMESHOPT_VERTEXCACHE, rgiAdjacency, NULL, NULL, NULL, &pMeshOpt);
- if (!FAILED(hr))
- {
- pmcMesh->pMesh->Release();
- pmcMesh->pMesh = pMeshOpt;
- pMeshOpt = NULL;
- }
-
- // Need to clone the mesh to be WRITEONLY since we will not now read back from it.
- LPD3DXMESH pMeshVid;
- hr = pmcMesh->pMesh->CloneMeshFVF(pmcMesh->pMesh->GetOptions() | D3DXMESH_WRITEONLY, pmcMesh->pMesh->GetFVF(),
- pDevice, &pMeshVid);
- if (!FAILED(hr))
- {
- pmcMesh->pMesh->Release();
- pmcMesh->pMesh = pMeshVid;
- pMeshVid = NULL;
- }
- }
-
-
- e_ExitNONINDEXED:
-
- GXRELEASE(pDevice);
-
- if (rgiAdjacency != NULL)
- {
- delete[] rgiAdjacency;
- }
-
- if (FAILED(hr))
- goto e_Exit;
-
- }
- else if (m_method == D3DINDEXED)
- {
- hr = pmcMesh->m_pSkinMesh->ConvertToIndexedBlendedMesh(D3DXMESH_SYSTEMMEM, pAdjacencyIn, 255, NULL,
- &pmcMesh->cpattr, &pmcMesh->m_pBoneCombinationBuf, &pmcMesh->pMesh);
- if (FAILED(hr))
- goto e_Exit;
-
- // Here we are talking of max vertex influence which we determine from
- // the FVF of the returned mesh
- if ((pmcMesh->pMesh->GetFVF() & D3DFVF_POSITION_MASK) != D3DFVF_XYZ)
- {
- pmcMesh->m_maxFaceInfl = ((pmcMesh->pMesh->GetFVF() & D3DFVF_POSITION_MASK) - D3DFVF_XYZRHW) / 2;
- }
- else
- {
- pmcMesh->m_maxFaceInfl = 1;
- }
- }
- else if (m_method == SOFTWARE)
- {
- hr = pmcMesh->m_pSkinMesh->GenerateSkinnedMesh
- (
- D3DXMESH_WRITEONLY, // options
- 0.0f, // minimumm bone weight allowed
- pAdjacencyIn, // adjacency of in-mesh
- pmcMesh->m_rgiAdjacency, // adjacency of out-mesh
- &pmcMesh->pMesh // out-mesh
- );
- if (FAILED(hr))
- goto e_Exit;
-
-
- hr = pmcMesh->pMesh->GetAttributeTable(NULL, &pmcMesh->cpattr);
-
- if (FAILED(hr))
- goto e_Exit;
-
-
- delete[] pmcMesh->m_pAttrTable;
-
- pmcMesh->m_pAttrTable = new D3DXATTRIBUTERANGE[pmcMesh->cpattr];
-
- if (pmcMesh->m_pAttrTable == NULL)
- {
- hr = E_OUTOFMEMORY;
-
- goto e_Exit;
- }
-
-
- hr = pmcMesh->pMesh->GetAttributeTable(pmcMesh->m_pAttrTable, NULL);
-
- if (FAILED(hr))
- goto e_Exit;
-
-
- hr = pmcMesh->m_pSkinMesh->GetMaxFaceInfluences(&pmcMesh->m_maxFaceInfl);
-
- if (FAILED(hr))
- goto e_Exit;
- }
-
- pmcMesh->m_Method = m_method;
-
- e_Exit:
-
- delete[] pAdjacencyIn;
-
- return hr;
- }
-
-
-
-
- HRESULT CMyD3DApplication::LoadMesh(LPDIRECTXFILEDATA pxofobjCur,
- DWORD options, DWORD fvf, LPDIRECT3DDEVICE8 pD3DDevice,
- SFrame *pframeParent)
- {
- HRESULT hr = S_OK;
- SMeshContainer *pmcMesh = NULL;
- LPD3DXBUFFER pbufMaterials = NULL;
- LPD3DXBUFFER pbufAdjacency = NULL;
- DWORD cchName;
- UINT cFaces;
- UINT iMaterial;
- LPDIRECT3DDEVICE8 m_pDevice = m_pd3dDevice;
-
- pmcMesh = new SMeshContainer();
- if (pmcMesh == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- hr = pxofobjCur->GetName(NULL, &cchName);
- if (FAILED(hr))
- goto e_Exit;
-
- if (cchName > 0)
- {
- pmcMesh->szName = new char[cchName];
- if (pmcMesh->szName == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- hr = pxofobjCur->GetName(pmcMesh->szName, &cchName);
- if (FAILED(hr))
- goto e_Exit;
- }
-
- hr = D3DXLoadSkinMeshFromXof(pxofobjCur, options, pD3DDevice, &pbufAdjacency, &pbufMaterials, &pmcMesh->cMaterials,
- &pmcMesh->m_pBoneNamesBuf, &pmcMesh->m_pBoneOffsetBuf, &pmcMesh->m_pSkinMesh);
- if (FAILED(hr))
- goto e_Exit;
-
- cFaces = pmcMesh->m_pSkinMesh->GetNumFaces();
-
- // Process skinning data
- if (pmcMesh->m_pSkinMesh->GetNumBones())
- {
- pmcMesh->m_pBoneMatrix = new D3DXMATRIX*[pmcMesh->m_pSkinMesh->GetNumBones()];
- if (pmcMesh->m_pBoneMatrix == NULL)
- goto e_Exit;
- pmcMesh->m_pBoneOffsetMat = reinterpret_cast<D3DXMATRIX*>(pmcMesh->m_pBoneOffsetBuf->GetBufferPointer());
- LPDWORD pAdjacencyIn = static_cast<LPDWORD>(pbufAdjacency->GetBufferPointer());
-
- pmcMesh->m_rgiAdjacency = new DWORD[cFaces * 3];
-
- if (pmcMesh->m_rgiAdjacency == NULL)
- {
- hr = E_OUTOFMEMORY;
-
- goto e_Exit;
- }
-
- memcpy(pmcMesh->m_rgiAdjacency, pAdjacencyIn, cFaces * 3 * sizeof(DWORD));
-
- hr = GenerateMesh(pmcMesh);
-
- if (FAILED(hr))
- goto e_Exit;
- }
- else
- {
- pmcMesh->m_pSkinMesh->GetOriginalMesh(&(pmcMesh->pMesh));
- pmcMesh->m_pSkinMesh->Release();
- pmcMesh->m_pSkinMesh = NULL;
- pmcMesh->cpattr = pmcMesh->cMaterials;
- }
-
- if ((pbufMaterials == NULL) || (pmcMesh->cMaterials == 0))
- {
- pmcMesh->rgMaterials = new D3DMATERIAL8[1];
- pmcMesh->pTextures = new LPDIRECT3DTEXTURE8[1];
- if (pmcMesh->rgMaterials == NULL || pmcMesh->pTextures == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- memset(pmcMesh->rgMaterials, 0, sizeof(D3DXMATERIAL));
- pmcMesh->rgMaterials[0].Diffuse.r = 0.5f;
- pmcMesh->rgMaterials[0].Diffuse.g = 0.5f;
- pmcMesh->rgMaterials[0].Diffuse.b = 0.5f;
- pmcMesh->rgMaterials[0].Specular = pmcMesh->rgMaterials[0].Diffuse;
- pmcMesh->pTextures[0] = NULL;
- }
- else
- {
- pmcMesh->rgMaterials = new D3DMATERIAL8[pmcMesh->cMaterials];
- pmcMesh->pTextures = new LPDIRECT3DTEXTURE8[pmcMesh->cMaterials];
- if (pmcMesh->rgMaterials == NULL || pmcMesh->pTextures == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- LPD3DXMATERIAL pMaterials = (LPD3DXMATERIAL)pbufMaterials->GetBufferPointer();
-
- for (iMaterial = 0; iMaterial < pmcMesh->cMaterials; iMaterial++)
- {
-
- pmcMesh->rgMaterials[iMaterial] = pMaterials[iMaterial].MatD3D;
-
- pmcMesh->pTextures[iMaterial] = NULL;
- if (pMaterials[iMaterial].pTextureFilename != NULL)
- {
- TCHAR szPath[MAX_PATH];
- DXUtil_FindMediaFile(szPath, pMaterials[iMaterial].pTextureFilename);
-
- hr = D3DXCreateTextureFromFile(m_pDevice, szPath, &(pmcMesh->pTextures[iMaterial]));
- if (FAILED(hr))
- pmcMesh->pTextures[iMaterial] = NULL;
- }
- }
- }
-
- // add the mesh to the parent frame
- pframeParent->AddMesh(pmcMesh);
- pmcMesh = NULL;
-
- e_Exit:
- delete pmcMesh;
-
- GXRELEASE(pbufAdjacency);
- GXRELEASE(pbufMaterials);
-
- return hr;
- }
-
-
-
-
- HRESULT CMyD3DApplication::LoadFrames(LPDIRECTXFILEDATA pxofobjCur, SDrawElement *pde,
- DWORD options, DWORD fvf, LPDIRECT3DDEVICE8 pD3DDevice,
- SFrame *pframeParent)
- {
- HRESULT hr = S_OK;
- LPDIRECTXFILEDATA pxofobjChild = NULL;
- LPDIRECTXFILEOBJECT pxofChild = NULL;
- const GUID *type;
- DWORD cbSize;
- D3DXMATRIX *pmatNew;
- SFrame *pframeCur;
- DWORD cchName;
-
- // Get the type of the object
- hr = pxofobjCur->GetType(&type);
- if (FAILED(hr))
- goto e_Exit;
-
-
- if (*type == TID_D3DRMMesh)
- {
- hr = LoadMesh(pxofobjCur, options, fvf, pD3DDevice, pframeParent);
- if (FAILED(hr))
- goto e_Exit;
- }
- else if (*type == TID_D3DRMFrameTransformMatrix)
- {
- hr = pxofobjCur->GetData(NULL, &cbSize, (PVOID*)&pmatNew);
- if (FAILED(hr))
- goto e_Exit;
-
- // update the parents matrix with the new one
- pframeParent->matRot = *pmatNew;
- pframeParent->matRotOrig = *pmatNew;
- }
- else if (*type == TID_D3DRMAnimationSet)
- {
- LoadAnimationSet(pxofobjCur, pde, options, fvf, pD3DDevice, pframeParent);
- }
- else if (*type == TID_D3DRMAnimation)
- {
- LoadAnimation(pxofobjCur, pde, options, fvf, pD3DDevice, pframeParent);
- }
- else if (*type == TID_D3DRMFrame)
- {
- pframeCur = new SFrame();
- if (pframeCur == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- hr = pxofobjCur->GetName(NULL, &cchName);
- if (FAILED(hr))
- goto e_Exit;
-
- if (cchName > 0)
- {
- pframeCur->szName = new char[cchName];
- if (pframeCur->szName == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto e_Exit;
- }
-
- hr = pxofobjCur->GetName(pframeCur->szName, &cchName);
- if (FAILED(hr))
- goto e_Exit;
- }
-
- pframeParent->AddFrame(pframeCur);
-
- // Enumerate child objects.
- // Child object can be data, data reference or binary.
- // Use QueryInterface() to find what type of object a child is.
- while (SUCCEEDED(pxofobjCur->GetNextObject(&pxofChild)))
- {
- // Query the child for it's FileData
- hr = pxofChild->QueryInterface(IID_IDirectXFileData,
- (LPVOID *)&pxofobjChild);
- if (SUCCEEDED(hr))
- {
- hr = LoadFrames(pxofobjChild, pde, options, fvf, pD3DDevice, pframeCur);
- if (FAILED(hr))
- goto e_Exit;
-
- GXRELEASE(pxofobjChild);
- }
-
- GXRELEASE(pxofChild);
- }
-
- }
-
- e_Exit:
- GXRELEASE(pxofobjChild);
- GXRELEASE(pxofChild);
- return hr;
- }
-
-
-
-
- HRESULT CMyD3DApplication::DeleteSelectedMesh()
- {
- if (m_pdeSelected != NULL)
- {
- SDrawElement *pdeCur = m_pdeHead;
- SDrawElement *pdePrev = NULL;
- while ((pdeCur != NULL) && (pdeCur != m_pdeSelected))
- {
- pdePrev = pdeCur;
- pdeCur = pdeCur->pdeNext;
- }
-
- if (pdePrev == NULL)
- {
- m_pdeHead = m_pdeHead->pdeNext;
- }
- else
- {
- pdePrev->pdeNext = pdeCur->pdeNext;
- }
-
- m_pdeSelected->pdeNext = NULL;
- if (m_pdeHead == m_pdeSelected)
- m_pdeHead = NULL;
- delete m_pdeSelected;
- m_pdeSelected = NULL;
- }
-
- return S_OK;
- }
-